<template>
  <div class="container-wf">
    <div class="c-header">
      <i class="iconfont icon-tishi1"></i>
      <i
        class="iconfont icon-icon-mianxing_fuzhi_cunchu-13"
        @click="SaveConfig"
      ></i>
    </div>
    <div class="c-main" ref="wfcontainer" @contextmenu.prevent="contextShow">
      <div
        class="item-1"
        @contextmenu.prevent="nodeContextShow($event, item)"
        v-for="item in nodeList"
        :key="item.id"
        :style="{ left: item.x + 'px', top: item.y + 'px' }"
      >
        <p hidden="true">{{ item.id }}</p>
        <p class="item-1-title">{{ item.nodeName }}</p>
        <p class="item-1-content">
          <span v-for="val in item.userList" style="margin: 3px">{{
            val
          }}</span>
        </p>
      </div>
    </div>
    <!-- 鼠标右键菜单 -->
    <div ref="customMenu" class="context-menu">
      <div v-if="mainMenuShow">
        <p class="menu-node menu-node-header" @click="AddNode">添加节点</p>
        <p class="menu-node">查看数据</p>
        <p class="menu-node">检查数据</p>
        <p class="menu-node">全选</p>
      </div>
      <div v-if="contentMainShow">
        <p class="menu-node menu-node-header" @click="DelNode">删除</p>
        <p class="menu-node" @click="EditNode">编辑基本信息</p>
        <p class="menu-node">配置审批权限</p>
        <p class="menu-node">配置附加动作</p>
      </div>
    </div>
    <!-- 节点信息添加弹窗 -->
    <el-dialog
      width="42%"
      :show-close="true"
      :visible.sync="addNodeInfoVisiable"
      :before-close="handleClose"
      center
      title="节点信息"
    >
      <el-form
        :label-position="labelPosition"
        label-width="80px"
        :model="nodeInfo"
        size="medium"
      >
        <el-form-item label="节点名称">
          <el-input v-model="nodeInfo.nodeName"></el-input>
        </el-form-item>
        <el-form-item label="节点顺序">
          <el-input v-model="nodeInfo.sort"></el-input>
        </el-form-item>
        <el-form-item label="节点类型">
          <el-select v-model="nodeInfo.type" placeholder="请选择节点类型">
            <el-option
              v-for="item in nodeTypeList"
              :label="item.name"
              :value="item.value"
              :key="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="审批模式">
          <el-select
            v-model="nodeInfo.approvalMode"
            placeholder="请选择审批模式"
          >
            <el-option
              v-for="item in approvalModes"
              :label="item.name"
              :value="item.value"
              :key="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="允许操作">
          <el-checkbox v-model="nodeInfo.forwarding">审批</el-checkbox>
          <el-checkbox v-model="nodeInfo.back">回退</el-checkbox>
          <el-checkbox v-model="nodeInfo.withdraw">撤销</el-checkbox>
          <el-checkbox v-model="nodeInfo.vote">否决</el-checkbox>
        </el-form-item>
        <el-form-item label="启用">
          <el-checkbox v-model="nodeInfo.isEnable"></el-checkbox>
        </el-form-item>
        <el-form-item label="审批页面">
          <el-input
            placeholder="请配置审批页面"
            v-model="nodeInfo.approvalPage"
          >
            <el-button
              slot="append"
              icon="el-icon-edit"
              @click="approvalPageSet(nodeInfo.approvalPage)"
            ></el-button>
          </el-input>
        </el-form-item>
        <el-form-item label="备注">
          <el-input
            v-model="nodeInfo.remark"
            placeholder="请输入备注"
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addNodeInfoVisiable = false">取 消</el-button>
        <el-button type="primary" @click="addNodeInfoVisiable = false"
          >确 定</el-button
        >
      </div>
    </el-dialog>
    <!-- 审批操作页面 -->
    <el-dialog
      width="35%"
      :show-close="true"
      :visible.sync="approvalConfigVisible"
      title="配置审批操作页面"
    >
      <div class="dialog-body">
        <el-row
          v-for="item in approvalViewList"
          :key="item.id"
          :gutter="20"
          align="middle"
          justify="center"
          type="flex"
          class="page-row-item"
        >
          <el-col :span="6">
            <el-tag color="#ebf9f6" type="success">{{ item.pageName }}</el-tag>
          </el-col>
          <el-col :span="14">
            <span>{{ item.pageUrl }}</span>
          </el-col>
          <el-col :span="4">
            <el-button
              size="mini"
              icon="el-icon-delete"
              @click="DelPageInfo(item)"
            ></el-button>
          </el-col>
        </el-row>
        <p align="center">
          <i
            class="el-icon-circle-plus-outline add-icon"
            @click="AddApprovalInfo"
          ></i>
        </p>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="SavePages">保 存</el-button>
      </div>
    </el-dialog>
    <!-- 审批页添加 -->
    <div class="approval-msgbox" v-show="approvalAddVisible">
      <h3 align="left">添加新的审批页</h3>
      <el-form
        label-position="top"
        label-width="80px"
        :model="approvalViewInfo"
      >
        <el-form-item label="输入审批页名称">
          <el-input v-model="approvalViewInfo.pageName"></el-input>
        </el-form-item>
        <el-form-item label="输入审批页地址">
          <el-input v-model="approvalViewInfo.pageUrl"></el-input>
        </el-form-item>
      </el-form>
      <div class="msgbox-footer">
        <el-button @click="approvalAddVisible = false">取 消</el-button>
        <el-button type="primary" @click="ApprovalInfoAdd"
          >保 存</el-button
        >
      </div>
    </div>
  </div>
</template>
  
  <script>
import { IsNullOrEmpty } from "@/utils/tools";
export default {
  data() {
    return {
      container: null,
      customMenu: null,
      mainMenuShow: true,
      contentMainShow: false,
      userList: ["管理员", "张三", "李四", "小李子", "诺兰"],
      nodeTypeList: [],
      approvalModes: [],
      hitRegion: ["c-main", "item-1"],
      selectedNode: null,
      addNodeInfoVisiable: false,
      approvalConfigVisible: false,
      approvalAddVisible: false,
      labelPosition: "right",
      nodeInfo: {
        nodeName: "新建审批节点",
        sort: 0,
        type: "01",
        approvalMode: "01",
        userList: ["管理员", "张三", "李四", "小李子", "诺兰", "王五"],
        x: 0,
        y: 0,
        forwarding: true,
        back: false,
        withdraw: false,
        vote: false,
        isEnable: false,
        approvalPage: "",
        remark: "",
      },
      nodeList: [
        {
          id: 1,
          nodeName: "价格浮动配置审批",
          sort: 1,
          type: "01",
          approvalMode: "01",
          userList: ["管理员", "张三", "李四", "小李子", "诺兰", "王五"],
          x: 200,
          y: 100,
          forwarding: true,
          back: false,
          withdraw: false,
          vote: false,
          isEnable: false,
          approvalPage:
            "测试审批页面:views/user/index.vue;项目进度审批:views/project/index.vue",
          remark: "",
        },
        {
          id: 2,
          nodeName: "项目进度审批",
          userList: ["管理员", "张三", "李四", "小李子", "诺兰", "王五"],
          sort: 2,
          type: "01",
          approvalMode: "01",
          x: 430,
          y: 200,
          forwarding: true,
          back: false,
          withdraw: false,
          vote: false,
          isEnable: false,
          approvalPage:
            "合同备案审批页面:views/contract/index.vue;项目进度审批:views/project/index.vue",
          remark: "",
        },
      ],
      approvalViewInfo: {
        id: 1,
        sort: 1,
        pageName: "测试审批页面",
        pageUrl: "views/user/index.vue",
      },
      approvalViewList: [],
    };
  },
  created() {
    this.getNodeTypes();
    this.getApprovalModes();
  },
  mounted() {
    this.InitDom();
  },
  methods: {
    getNodeTypes() {
      this.nodeTypeList.push({
        id: 1,
        name: "自动（超时后，由系统按照【审批】操作自动审批",
        value: "01",
      });
      this.nodeTypeList.push({
        id: 2,
        name: "手动（必须人工审核）",
        value: "02",
      });
    },
    getApprovalModes() {
      this.approvalModes.push({ id: 1, name: "串签", value: "01" });
      this.approvalModes.push({ id: 2, name: "并签", value: "02" });
      this.approvalModes.push({ id: 3, name: "汇签", value: "03" });
    },
    approvalPageSet(approvalPage) {
      this.approvalConfigVisible = true;
      if (!IsNullOrEmpty(approvalPage)) {
        let appArr = approvalPage.split(";");
        appArr.forEach((item, idx) => {
          let valArr = item.split(":");
          this.approvalViewList.push({
            id: idx,
            sort: idx,
            pageName: valArr[0],
            pageUrl: valArr[1],
          });
        });
      }
    },
    DelPageInfo(item) {
      this.approvalViewList = this.approvalViewList.filter(
        (p) => p.id !== item.id
      );
    },
    SavePages() {
      this.approvalConfigVisible = false;
      let workingUrl = this.approvalViewList
        .map((p) => {
          return `${p.pageName}:${p.pageUrl}`;
        })
       .join(";");
       
       this.approvalViewList = [];
      this.nodeInfo.approvalPage = workingUrl;
    },
    AddApprovalInfo() {
      this.approvalAddVisible = true;
    },
    ApprovalInfoAdd(){
        let item = this.approvalViewList[this.approvalViewList.length - 1]
        this.approvalViewInfo.id = item == null ? 1 : item.id + 1;
        this.approvalViewInfo.sort = item == null ? 1: item.sort + 1;
        this.approvalViewList.push(this.approvalViewInfo);
        this.approvalAddVisible = false;
    },
    InitDom() {
      // 获取自定义菜单元素
      this.container = this.$refs.wfcontainer;
      this.customMenu = this.$refs.customMenu;

      // 监听全局点击事件，隐藏菜单
      document.addEventListener("click", this.contextCancel);

      // 给container中已存在的节点绑定事件处理程序
      let nodes = this.container.children;
      for (let i = 0; i < nodes.length; i++) {
        if (nodes[i].classList.contains("item-1")) {
          this.InitNodeEvent(nodes[i]);
        }
      }
    },
    contextShow(e) {
      // 重置为默认状态
      this.mainMenuShow = false;
      this.contentMainShow = false;

      // 禁止默认右键菜单
      e.preventDefault();
      // 获取鼠标点击的元素
      const clickedElement = e.target;
      const parentElement = e.target.parentElement;
      // console.log('parent element: ',e.target.parentElement)

      if (clickedElement.classList.contains("item-1")) {
        this.contentMainShow = true;
        this.selectedNode = clickedElement;
      } else if (parentElement.classList.contains("item-1")) {
        this.contentMainShow = true;
        this.selectedNode = parentElement;
      } else if (clickedElement.classList.contains("c-main")) {
        this.mainMenuShow = true;
        this.selectedNode = null;
      } else {
        this.selectedNode = null;
      }

      // 获取鼠标点击位置
      const mouseX = e.clientX;
      const mouseY = e.clientY;

      // 输出被点击的元素类型
      // console.log("Clicked element:", clickedElement);

      // 显示自定义菜单
      this.customMenu.style.left = mouseX + "px";
      this.customMenu.style.top = mouseY + "px";
      this.customMenu.style.display = "block";
    },
    nodeContextShow(e, item) {
      this.selectedNode = e.target;
      this.nodeInfo = item;
    },
    contextCancel() {
      this.customMenu.style.display = "none";
    },
    InitNodeEvent(item) {
      // 初始位置
      var offsetX = 0;
      var offsetY = 0;
      var isDragging = false;

      // 当鼠标按下时，开始拖动
      item.addEventListener("mousedown", (e) => {
        isDragging = true;
        offsetX = e.clientX - item.offsetLeft; // 获取鼠标按下时与控件左边缘的距离
        offsetY = e.clientY - item.offsetTop; // 获取鼠标按下时与控件上边缘的距离

        // 禁止选中文本，避免拖动时出现文本选中的问题
        item.style.userSelect = "none";
      });

      // 当鼠标移动时，如果正在拖动，则更新控件的位置
      item.addEventListener("mousemove", (e) => {
        if (isDragging) {
          let p = item.firstElementChild;
          let id = parseInt(p.innerText);
          var x = e.clientX - offsetX; // 计算新的 X 坐标
          var y = e.clientY - offsetY; // 计算新的 Y 坐标
          item.style.left = x + "px"; // 更新控件的左侧位置
          item.style.top = y + "px"; // 更新控件的顶部位置
          let node = this.nodeList.find((node) => node.id == id);
          node.x = x;
          node.y = y;
        }
      });

      // 当鼠标松开时，停止拖动
      item.addEventListener("mouseup", () => {
        isDragging = false;
        item.style.userSelect = "auto"; // 恢复文本选中
      });
    },
    handleClose(done) {
      this.$confirm("确认关闭？")
        .then((_) => {
          done();
        })
        .catch((_) => {});
    },
    AddNode(e) {
      let hitElem = e.target;
      const mouseX = hitElem.clientX;
      const mouseY = hitElem.clientY;

      this.nodeInfo.x = mouseX;
      this.nodeInfo.y = mouseY;
    },
    EditNode() {
      this.addNodeInfoVisiable = true;
    },
    DelNode() {
      if (this.selectedNode != null) {
        this.container.removeChild(this.selectedNode);
      }
    },
    SaveConfig() {
      /*
          this.$message({
              message: '操作成功',
              type: 'success',
              duration: 5000,
              showClose: true,
              customClass: 'my-custom-message',
              center: true
          });
       */
      this.$message.success("内容已保存");
    },
  },
  beforeDestroy() {
    // 在组件销毁前移除事件监听
    this.container.removeEventListener("contextmenu", this.contextShow);
    this.container.removeEventListener("click", this.contextCancel);
  },
};
</script>
  
  <style lang="scss" scoped>
.container-wf {
  width: 100%;
  height: calc(100vh - 70px);
  border-radius: 4px;
  box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.4);

  .c-header {
    height: 5%;
    border-bottom: 1px solid #e4e4e4;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    .iconfont {
      margin: 0 25px 0 25px;
      font-size: 30px;
      cursor: pointer;
    }
    .iconfont:hover {
      color: orange !important;
    }
  }
  .el-form {
    .el-form-item {
      .el-select {
        width: 100%;
      }
      .el-input {
        width: 100%;
      }
      .el-form-item__label {
        font-weight: 600 !important;
      }
    }
  }
  .dialog-body {
    .page-row-item {
      margin: 0px 0px 10px 0px;
      box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
      padding: 5px;
    }
    .add-icon {
      text-align: center;
      font-size: 40px;
      color: #63cdb8;
    }
    .add-icon:hover {
      color: coral;
    }
  }
  .approval-msgbox {
    position: absolute;
    top: calc(50% - 200px);
    left: calc(50% - 235px);
    z-index: 3000;
    width: 570px;
    height: fit-content;
    padding: 15px 20px 50px 20px;
    background: white;
    border-radius: 4px;
    box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);

    .msgbox-footer {
      position: absolute;
      bottom: 15px;
      right: 20px;
    }
  }
}
</style>